package com.wyzz.hr.bo.impl;

import java.math.BigDecimal;
import java.util.*;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.*;

import com.wyzz.hr.base.Status;
import com.wyzz.hr.bo.IAttendshiftBO;
import com.wyzz.hr.bo.IEmpshiftBo;
import com.wyzz.hr.bo.ILeavebalanceBO;
import com.wyzz.hr.bo.ILeavecalendarBO;
import com.wyzz.hr.bo.ILeavetypeBO;
import com.wyzz.hr.bo.IOvertimerequestBo;
import com.wyzz.hr.bo.IOvertimetxusedBO;
import com.wyzz.hr.dao.ILeaverequestDAO;
import com.wyzz.hr.pojo.Attendshift;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Empshift;
import com.wyzz.hr.pojo.Leavebalance;
import com.wyzz.hr.pojo.Leaverequest;
import com.wyzz.hr.pojo.Leavetype;
import com.wyzz.hr.pojo.Overtimerequest;
import com.wyzz.hr.pojo.Overtimetxused;
import com.wyzz.hr.spring.SpringBeanFactory;
import com.wyzz.hr.util.DatabaseSysConfigManager;
import com.wyzz.hr.util.DateUtil;
import com.wyzz.hr.util.MyTools;
import com.wyzz.hr.util.StringUtil;

public class LrDataCheckImpl {

	public LrDataCheckImpl() {
	}

	public String getLrTimeInfo(Leaverequest lr) {
		String msgReturnDays = "\u60A8\u8BF7\u4E86{0}\u5929{1}\uFF0C\u786E\u5B9A\u8981\u63D0\u4EA4\u672C\u6B21\u8BF7\u5047\u5417\uFF1F";
		String msgReturnHours = "\u60A8\u8BF7\u4E86{0}\u5C0F\u65F6({1}\u5929){2}\uFF0C\u786E\u5B9A\u8981\u63D0\u4EA4\u672C\u6B21\u8BF7\u5047\u5417\uFF1F";
		Employee emp = (Employee) attendBo.loadObject(Employee.class, lr
				.getLrEmpNo().getId(), null, new boolean[0]);
		lr.setLrEmpNo(emp);
		Integer empShiftType = lr.getLrEmpNo().getEmpShiftType();
		List lcList = null;
		List empShiftList = null;
		Attendshift defaultAs = null;
		if (empShiftType.intValue() == 0 || empShiftType.intValue() == 2) {
			lcList = lc_BO.getCalendarListByDay(lr.getLrStartDate(), lr
					.getLrEndDate());
			defaultAs = attendBo.getDefaultAttendshiftByEmp(lr.getLrEmpNo());
			empShiftList = generateDefaultESList(lr.getLrStartDate(), lr
					.getLrEndDate(), lr.getLrEmpNo(), defaultAs, lcList);
		} else {
			System.out.println("1111111111");
			empShiftList = getEmpShiftBo().getEmpShiftList(lr.getLrStartDate(),
					lr.getLrEndDate(), lr.getLrEmpNo().getId());
		}
		String result = setHourAndDay(empShiftList, lr);
		if (!"SUCC".equals(result))
			return result;
		if (lr.getLrStartApm() != null)
			return StringUtil.message(msgReturnDays, new Object[] {
					lr.getLrTotalDays(), lr.getLrLtNo().getLtName() });
		else
			return StringUtil.message(msgReturnHours, new Object[] {
					lr.getLrTotalHours(), lr.getLrTotalDays(),
					lr.getLrLtNo().getLtName() });
	}

	public String validateLRDate(Leaverequest lr) {
		String msgNoWorkDayIncl = "{0}\u8BF7\u5047\u672A\u5305\u542B\u4EFB\u4F55\u5DE5\u4F5C\u65E5\uFF01";
		Integer empShiftType = lr.getLrEmpNo().getEmpShiftType();
		String empShiftDesc = "\u5458\u5DE5";
		if (empShiftType.intValue() == 3)
			empShiftDesc = "\u6392\u73ED\u5458\u5DE5";
		List lcList = null;
		List empShiftList = null;
		Attendshift defaultAs = null;
		if (empShiftType.intValue() == 0 || empShiftType.intValue() == 2) {
			defaultAs = attendBo.getDefaultAttendshiftByEmp(lr.getLrEmpNo());
			lcList = lc_BO.getCalendarListByDay(lr.getLrStartDate(), lr
					.getLrEndDate());
			empShiftList = generateDefaultESList(lr.getLrStartDate(), lr
					.getLrEndDate(), lr.getLrEmpNo(), defaultAs, lcList);
		} else {
			empShiftList = getEmpShiftBo().getEmpShiftList(lr.getLrStartDate(),
					lr.getLrEndDate(), lr.getLrEmpNo().getId());
		}
		if (empShiftList.size() == 0)
			return StringUtil.message(msgNoWorkDayIncl,
					new Object[] { empShiftDesc });
		String info = setHourAndDay(empShiftList, lr);
		if (!"SUCC".equals(info)) {
			return info;
		} else {
			lr.setHoursPerDay(ExaminDateUtil.getDefaultHoursPerDay());
			return "SUCC";
		}
	}

	public String setHourAndDay(List empShiftList, Leaverequest lr) {
		String msgNightShift = "\u5B58\u5728\u9694\u591C\u73ED\u6B21\uFF0C\u5FC5\u987B\u6309\u5C0F\u65F6\u8BF7\u5047\uFF01";
		String msgShiftErr = "\u73ED\u6B21\u65E0\u6CD5\u533A\u5206\u4E0A\u4E0B\u5348\uFF0C\u5FC5\u987B\u6309\u5C0F\u65F6\u8BF7\u5047\uFF01";
		String msgNoWorkDay = "{0}\u8BF7\u5047{1}\u65E5\u671F\u4E0D\u662F\u5DE5\u4F5C\u65E5\uFF01";
		String msgNoShiftIncl = "{0}\u8BF7\u5047{1}\u65F6\u95F4\u4E0D\u5728\u60A8\u7684\u73ED\u6B21\u4E2D\uFF01";
		Integer empShiftType = lr.getLrEmpNo().getEmpShiftType();
		String empShiftDesc = "\u5458\u5DE5";
		if (empShiftType.intValue() == 3)
			empShiftDesc = "\u6392\u73ED\u5458\u5DE5";
		double totalHours = 0.0D;
		double totalDays = 0.0D;
		if (lr.isApplyLRByDay()) {
			if (empShiftList.size() == 0)
				return StringUtil
						.message(msgNoWorkDay, new Object[] { "", "" });
			String info = checkShiftsValid(empShiftList, lr.getLrStartDate(),
					lr.getLrEndDate());
			if ("NIGHTSHIFT".equals(info))
				return msgNightShift;
			if ("SHIFTERR".equals(info))
				return msgShiftErr;
			if (DateUtil.compareTwoDay(((Empshift) empShiftList.get(0))
					.getEmpshiftDate(), lr.getLrStartDate()) != 0)
				return StringUtil.message(msgNoWorkDay, new Object[] {
						empShiftDesc, "\u5F00\u59CB" });
			if (DateUtil.compareTwoDay(((Empshift) empShiftList
					.get(empShiftList.size() - 1)).getEmpshiftDate(), lr
					.getLrEndDate()) != 0)
				return StringUtil.message(msgNoWorkDay, new Object[] {
						empShiftDesc, "\u7ED3\u675F" });
			double hours = 0.0D;
			for (int i = 0; i < empShiftList.size(); i++) {
				Empshift empShift = (Empshift) empShiftList.get(i);
				String attsSession = empShift.getEmpshiftShiftNo()
						.getAttsSession();
				if (i == 0) {
					Date shiftDateTime[] = ExaminDateUtil
							.getSplitDateByAttendShift(lr.getLrStartDate(),
									attsSession);
					if (lr.getLrStartApm() == null)
						lr.setLrStartApm(Integer.valueOf(0));
					if (lr.getLrStartApm().intValue() == 0) {
						lr.setLrStartDate(shiftDateTime[0]);
					} else {
						lr.setLrStartDate(shiftDateTime[2]);
						hours = (double) DateUtil.dateDiff(shiftDateTime[2],
								shiftDateTime[3], 12) / 60D;
					}
				}
				if (i == empShiftList.size() - 1) {
					Date shiftDateTime[] = ExaminDateUtil
							.getSplitDateByAttendShift(lr.getLrEndDate(),
									attsSession);
					if (lr.getLrEndApm() == null)
						lr.setLrEndApm(Integer.valueOf(1));
					if (lr.getLrEndApm().intValue() == 0) {
						lr.setLrEndDate(shiftDateTime[1]);
						hours = (double) DateUtil.dateDiff(shiftDateTime[0],
								shiftDateTime[1], 12) / 60D;
					} else {
						lr.setLrEndDate(shiftDateTime[3]);
					}
				}
				if (i == 0 && lr.getLrStartApm().intValue() == 1
						|| i == empShiftList.size() - 1
						&& lr.getLrEndApm().intValue() == 0) {
					totalHours += hours;
					totalDays += 0.5D;
				} else {
					totalHours += empShift.getEmpshiftShiftNo()
							.getAttsWorkingHour().doubleValue();
					totalDays++;
				}
			}

		} else {
			Map dbMap = DatabaseSysConfigManager.getInstance().getProperties();
			String cardCalcday = (String) dbMap.get("sys.shift.card.calcday");
			String leaveMode = (String) dbMap.get("sys.examin.leave.mode");
			String hourtodayMode = (String) dbMap
					.get("sys.examin.hourtoday.mode");
			double totalHoursPerDay = 0.0D;
			for (int i = 0; i < empShiftList.size(); i++) {
				Empshift empShift = (Empshift) empShiftList.get(i);
				if (i == 0) {
					int inShift = getEmpShiftBo().isInWorkShift(
							lr.getLrStartDate(), empShiftList).intValue();
					if (inShift == 0 || inShift == 3)
						return StringUtil.message(msgNoShiftIncl, new Object[] {
								empShiftDesc, "\u5F00\u59CB" });
					totalHoursPerDay = (double) ExaminDateUtil.minutesInShift(
							lr.getLrStartDate(), lr.getLrEndDate(), empShift
									.getEmpshiftDate(), empShift
									.getEmpshiftShiftNo().getAttsSession()) / 60D;
				}
				if (i == empShiftList.size() - 1) {
					int inShift = getEmpShiftBo().isInWorkShift(
							lr.getLrEndDate(), empShiftList).intValue();
					if (inShift == 0 || inShift == 1)
						return StringUtil.message(msgNoShiftIncl, new Object[] {
								empShiftDesc, "\u7ED3\u675F" });
					totalHoursPerDay = (double) ExaminDateUtil.minutesInShift(
							lr.getLrStartDate(), lr.getLrEndDate(), empShift
									.getEmpshiftDate(), empShift
									.getEmpshiftShiftNo().getAttsSession()) / 60D;
				}
				if (i != 0 && i != empShiftList.size() - 1)
					totalHoursPerDay = empShift.getEmpshiftShiftNo()
							.getAttsWorkingHour().doubleValue();
				totalHours += totalHoursPerDay;
				if ("0".equals(hourtodayMode))
					totalDays += ExaminDateUtil.convertHourToDay(
							new BigDecimal(totalHoursPerDay), cardCalcday,
							empShift.getEmpshiftShiftNo()).doubleValue();
				else
					totalDays += ExaminDateUtil.convertHourToDay(
							new BigDecimal(totalHoursPerDay), leaveMode,
							empShift.getEmpshiftShiftNo()).doubleValue();
			}

		}
		lr.setLrTotalHours(new BigDecimal(totalHours));
		lr.setLrTotalDays(new BigDecimal(totalDays));
		return "SUCC";
	}

	public List generateDefaultESList(Date startDate, Date endDate,
			Employee emp, Attendshift defaultShift, List lcList) {
		List list = new ArrayList();
		Date temp = (Date) startDate.clone();
		for (temp = DateUtil.parseDateByFormat(DateUtil.formatDate(temp),
				"yyyy-MM-dd"); temp.compareTo(endDate) <= 0; temp = DateUtil
				.dateAdd(temp, 1))
			if (1 == lc_BO.isACalendarDay(temp, lcList, emp.getEmpLocationNo())) {
				Empshift shift = new Empshift(null, emp, defaultShift, temp);
				list.add(shift);
			}

		return list;
	}

	private String checkShiftsValid(List empshiftList, Date startDate,
			Date endDate) {
		if (empshiftList == null)
			return "SUCC";
		startDate = DateUtil.convDateTimeToDate(startDate);
		endDate = DateUtil.convDateTimeToDate(endDate);
		Attendshift shift = null;
		for (Iterator it = empshiftList.iterator(); it.hasNext();) {
			Empshift empshift = (Empshift) it.next();
			if (empshift.getEmpshiftDate().compareTo(startDate) >= 0
					&& empshift.getEmpshiftDate().compareTo(endDate) <= 0) {
				shift = empshift.getEmpshiftShiftNo();
				if (shift.getAttsNightShift().intValue() == 1)
					return "NIGHTSHIFT";
				if (shift.getAttsSession().split(",").length != 2)
					return "SHIFTERR";
			}
		}

		return "SUCC";
	}

	public String validateLRConflict(Leaverequest lr) {
		String msgIDConflict = "\u4E0E\u7F16\u53F7\u4E3A{0}\u7684\u8BF7\u5047\u5355\u5B58\u5728\u65F6\u95F4\u51B2\u7A81\uFF01";
		String msgLTNotSetup = "{0}\u5E74\u7684{1}\u989D\u5EA6\u672A\u8BBE\u7F6E\uFF01";
		String msgLTNotApply = "{0}\u5E74\u7684{1}\u7981\u6B62\u7533\u8BF7\uFF01";
		int repeatID = hasDateRepeat(lr, lr.getLrStartDate(),
				lr.getLrEndDate(), Status.PROCESS_VALID);
		if (repeatID != -1)
			return StringUtil.message(msgIDConflict, new Object[] { Integer
					.valueOf(repeatID) });
		String info = checkOther(lr);
		if (!"SUCC".equals(info))
			return info;
		Leavetype lt = lr.getLrLtNo();
		if (lt.getLtSpecialCat().intValue() == 1
				|| lt.getLtSpecialCat().intValue() == 5) {
			int calYear = DateUtil.getYear(lr.getLrStartDate());
			Leavebalance lb = lb_BO
					.getLeavebalance(lr.getLrEmpNo(), (new StringBuilder())
							.append("").append(calYear).toString(), lt);
			if (lb == null)
				return StringUtil.message(msgLTNotSetup, new Object[] {
						(new StringBuilder()).append("").append(calYear)
								.toString(), lt.getLtName() });
			if (lb.getLbStatus().intValue() != 2)
				return StringUtil.message(msgLTNotApply, new Object[] {
						(new StringBuilder()).append("").append(calYear)
								.toString(), lt.getLtName() });
			if (lt.getLtSpecialCat().intValue() == 1)
				return checkAnnual(lr, lt, lb);
			if (lt.getLtSpecialCat().intValue() == 5)
				return checkSick02(lr, lt, lb);
		}
		return "SUCC";
	}

	public String checkOther(Leaverequest lr) {
		String msgTooSmall = "{0}\u6BCF\u6B21\u8BF7\u5047\u65F6\u95F4\u4E0D\u80FD\u5C11\u4E8E{1}{2}\uFF01";
		String msgTooBig = "{0}\u6BCF\u6B21\u8BF7\u5047\u65F6\u95F4\u4E0D\u80FD\u5927\u4E8E{1}{2}\uFF01";
		GregorianCalendar startCalendar = new GregorianCalendar();
		startCalendar.setTime(lr.getLrEndDate());
		ILeavetypeBO ltBo = (ILeavetypeBO) SpringBeanFactory
				.getBean("leavetypeBO");
		Leavetype lt = ltBo.getLeavetype(lr.getLrLtNo().getLtNo());
		double minPermitDays = 0.0D;
		double minPermitHours = 0.0D;
		if (lt.getLtMinApplyDays() != null) {
			minPermitDays = lt.getLtMinApplyDays().doubleValue();
			if (minPermitDays > 0.0D
					&& minPermitDays > lr.getLrTotalDays().doubleValue())
				return StringUtil.message(msgTooSmall,
						new Object[] { lt.getLtName(),
								Double.valueOf(minPermitDays), "\u5929" });
		} else if (lt.getLtMinApplyHours() != null) {
			minPermitHours = lt.getLtMinApplyHours().doubleValue();
			if (minPermitHours > 0.0D
					&& minPermitHours > lr.getLrTotalHours().doubleValue())
				return StringUtil.message(msgTooSmall, new Object[] {
						lt.getLtName(), Double.valueOf(minPermitHours),
						"\u5C0F\u65F6" });
		}
		double maxPermitDays = 0.0D;
		double maxPermitHours = 0.0D;
		if (lt.getLtMaxApplyDays() != null) {
			maxPermitDays = lt.getLtMaxApplyDays().doubleValue();
			if (maxPermitDays > 0.0D
					&& maxPermitDays < lr.getLrTotalDays().doubleValue())
				return StringUtil.message(msgTooBig,
						new Object[] { lt.getLtName(),
								Double.valueOf(maxPermitDays), "\u5929" });
		} else if (lt.getLtMaxApplyHours() != null) {
			maxPermitHours = lt.getLtMaxApplyHours().doubleValue();
			if (maxPermitHours > 0.0D
					&& maxPermitHours < lr.getLrTotalHours().doubleValue())
				return StringUtil.message(msgTooBig, new Object[] {
						lt.getLtName(), Double.valueOf(maxPermitHours),
						"\u5C0F\u65F6" });
		}
		return "SUCC";
	}

	private List getTiaoxiuOrList(Leaverequest lr) {
		String tiaoxiuMatchStr = (String) DatabaseSysConfigManager
				.getInstance().getProperties().get("sys.examin.tiaoxiu.match");
		int tiaoxiuMatch = StringUtils.isEmpty(tiaoxiuMatchStr) ? 0 : Integer
				.parseInt(tiaoxiuMatchStr);
		List tiaoxiuOrList = or_Bo.getEmpAllTiaoxiuOrList(lr.getLrEmpNo(),
				statusSet_approved, lr.getLrStartDate(), Integer
						.valueOf(tiaoxiuMatch));
		return tiaoxiuOrList;
	}

	public String checkTiaoXiuExp(Leaverequest lr) {
		String info = "SUCC";
		if (lr.getLrId() != null && lr.getLrStatus().intValue() != 21) {
			double oldTotalHours = 0.0D;
			double newTotalHours = lr.getLrTotalHours().doubleValue();
			if (newTotalHours == 0.0D)
				return "\u8BF7\u5047\u65F6\u957F\u4E0D\u80FD\u4E3A0\uFF01";
			IOvertimetxusedBO overtimetxusedBO = (IOvertimetxusedBO) SpringBeanFactory
					.getBean("overtimetxusedBO");
			List oldOvertimetxusedList = overtimetxusedBO
					.searchOvertimetxusedByLrId(lr.getLrId());
			if (oldOvertimetxusedList == null)
				return info;
			for (Iterator i$ = oldOvertimetxusedList.iterator(); i$.hasNext();) {
				Overtimetxused otu = (Overtimetxused) i$.next();
				oldTotalHours += otu.getOtuHours().doubleValue();
			}

			if (oldTotalHours == newTotalHours)
				return info;
			if (newTotalHours < oldTotalHours) {
				lrModifyAndDecrease(lr, oldOvertimetxusedList, oldTotalHours);
				return info;
			}
			double modifyHours = newTotalHours - oldTotalHours;
			modifyHours = lrModifyAndIncrease(lr, oldOvertimetxusedList,
					modifyHours);
			if (modifyHours != 0.0D)
				info = (new StringBuilder())
						.append("\u53EF\u7528\u8C03\u4F11\u53EA\u6709")
						.append(newTotalHours - oldTotalHours - modifyHours)
						.append(
								"\u5C0F\u65F6\uFF0C\u8BF7\u51CF\u5C11\u7533\u8BF7\u65F6\u95F4\uFF01")
						.toString();
		} else {
			double lrHours = lr.getLrTotalHours().doubleValue();
			List tiaoxiuOrList = getTiaoxiuOrList(lr);
			lrHours = checkAndAddOtu(lr, tiaoxiuOrList, lrHours, Integer
					.valueOf(1));
			if (lrHours != 0.0D)
				info = (new StringBuilder())
						.append("\u53EF\u7528\u8C03\u4F11\u53EA\u6709")
						.append(lr.getLrTotalHours().doubleValue() - lrHours)
						.append(
								"\u5C0F\u65F6\uFF0C\u8BF7\u51CF\u5C11\u7533\u8BF7\u65F6\u95F4\uFF01")
						.toString();
		}
		return info;
	}

	private double lrModifyAndIncrease(Leaverequest lr,
			List oldOvertimetxusedList, double modifyHours) {
		double hourPerDay = lr.getHoursPerDay();
		List updateOvertimetxusedList = new ArrayList();
		List needUpdateOvertimerequestList = new ArrayList();
		List hasModifyOrList = new ArrayList();
		for (int i = oldOvertimetxusedList.size() - 1; i >= 0; i--) {
			Overtimetxused otu = (Overtimetxused) oldOvertimetxusedList.get(i);
			Overtimerequest or = otu.getOtuOrId();
			if (or.getOrTiaoxiuHoursRemain().doubleValue() == 0.0D)
				continue;
			hasModifyOrList.add(or);
			if (or.getOrTiaoxiuHoursRemain().doubleValue() > modifyHours) {
				otu.setOtuHours(new BigDecimal(otu.getOtuHours().doubleValue()
						+ modifyHours));
				otu.setOtuDays(new BigDecimal(otu.getOtuHours().doubleValue()
						/ hourPerDay));
				updateOvertimetxusedList.add(otu);
				or.setOrTiaoxiuHoursRemain(new BigDecimal(or
						.getOrTiaoxiuHoursRemain().doubleValue()
						- modifyHours));
				needUpdateOvertimerequestList.add(or);
				modifyHours = 0.0D;
				break;
			}
			if (or.getOrTiaoxiuHoursRemain().doubleValue() == modifyHours) {
				otu.setOtuHours(new BigDecimal(otu.getOtuHours().doubleValue()
						+ modifyHours));
				otu.setOtuDays(new BigDecimal(otu.getOtuHours().doubleValue()
						/ hourPerDay));
				updateOvertimetxusedList.add(otu);
				or.setOrTiaoxiuHoursRemain(new BigDecimal(0.0D));
				needUpdateOvertimerequestList.add(or);
				modifyHours = 0.0D;
				break;
			}
			otu.setOtuHours(new BigDecimal(otu.getOtuHours().doubleValue()
					+ or.getOrTiaoxiuHoursRemain().doubleValue()));
			otu.setOtuDays(new BigDecimal(otu.getOtuHours().doubleValue()
					/ hourPerDay));
			updateOvertimetxusedList.add(otu);
			modifyHours -= or.getOrTiaoxiuHoursRemain().doubleValue();
			or.setOrTiaoxiuHoursRemain(new BigDecimal(0.0D));
			needUpdateOvertimerequestList.add(or);
		}

		lr.setUpdateOvertimerequestList(needUpdateOvertimerequestList);
		lr.setUpdateOvertimetxusedList(updateOvertimetxusedList);
		if (modifyHours == 0.0D)
			return 0.0D;
		Overtimetxused otu = (Overtimetxused) oldOvertimetxusedList.get(0);
		int maxSeq = otu.getOtuSeq().intValue() + 1;
		List tiaoxiuOrList = getTiaoxiuOrList(lr);
		if (!hasModifyOrList.isEmpty())
			tiaoxiuOrList.removeAll(hasModifyOrList);
		if (tiaoxiuOrList.isEmpty())
			return modifyHours;
		else
			return checkAndAddOtu(lr, tiaoxiuOrList, modifyHours, Integer
					.valueOf(maxSeq));
	}

	private void lrModifyAndDecrease(Leaverequest lr,
			List oldOvertimetxusedList, double oldTotalHours) {
		List updateOvertimetxusedList = new ArrayList();
		List deleteOvertimetxusedList = new ArrayList();
		List needUpdateOvertimerequestList = new ArrayList();
		double modifyHours = oldTotalHours - lr.getLrTotalHours().doubleValue();
		Iterator i$ = oldOvertimetxusedList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Overtimetxused overtimetxused = (Overtimetxused) i$.next();
			Overtimerequest or = overtimetxused.getOtuOrId();
			if (overtimetxused.getOtuHours().doubleValue() > modifyHours) {
				or.setOrTiaoxiuHoursRemain(new BigDecimal(or
						.getOrTiaoxiuHoursRemain().doubleValue()
						+ modifyHours));
				needUpdateOvertimerequestList.add(or);
				overtimetxused.setOtuHours(new BigDecimal(overtimetxused
						.getOtuHours().doubleValue()
						- modifyHours));
				overtimetxused.setOtuDays(new BigDecimal(overtimetxused
						.getOtuHours().doubleValue()
						/ lr.getHoursPerDay()));
				updateOvertimetxusedList.add(overtimetxused);
				break;
			}
			if (overtimetxused.getOtuHours().doubleValue() == modifyHours) {
				or.setOrTiaoxiuHoursRemain(new BigDecimal(or
						.getOrTiaoxiuHoursRemain().doubleValue()
						+ modifyHours));
				needUpdateOvertimerequestList.add(or);
				deleteOvertimetxusedList.add(overtimetxused);
				break;
			}
			or.setOrTiaoxiuHoursRemain(new BigDecimal(or
					.getOrTiaoxiuHoursRemain().doubleValue()
					+ overtimetxused.getOtuHours().doubleValue()));
			needUpdateOvertimerequestList.add(or);
			deleteOvertimetxusedList.add(overtimetxused);
			modifyHours -= overtimetxused.getOtuHours().doubleValue();
		} while (true);
		lr.setDeleteOvertimetxUsedList(deleteOvertimetxusedList);
		lr.setUpdateOvertimetxusedList(updateOvertimetxusedList);
		lr.setUpdateOvertimerequestList(needUpdateOvertimerequestList);
	}

	private double checkAndAddOtu(Leaverequest lr, List tiaoxiuOrList,
			double lrHours, Integer otuSeq) {
		double hourPerDay = lr.getHoursPerDay();
		List updateOvertimetxusedList = new ArrayList();
		List needUpdateOvertimerequestList = new ArrayList();
		Iterator iter = tiaoxiuOrList.iterator();
		Overtimerequest tiaoxiuOr = null;
		Overtimetxused overtimetxused = null;
		do {
			if (!iter.hasNext())
				break;
			tiaoxiuOr = (Overtimerequest) iter.next();
			if (tiaoxiuOr.getOrTiaoxiuExpire() != null
					&& tiaoxiuOr.getOrTiaoxiuExpire().compareTo(
							lr.getLrStartDate()) < 0) {
				iter.remove();
				continue;
			}
			double tiaoxiuHours = tiaoxiuOr.getOrTiaoxiuHoursRemain()
					.doubleValue();
			if (lrHours > tiaoxiuHours) {
				overtimetxused = new Overtimetxused();
				overtimetxused.setOtuLrId(lr);
				overtimetxused.setOtuOrId(tiaoxiuOr);
				overtimetxused.setOtuHours(new BigDecimal(tiaoxiuHours));
				overtimetxused.setOtuDays(new BigDecimal(tiaoxiuHours
						/ hourPerDay));
				overtimetxused.setOtuSeq(otuSeq);
				updateOvertimetxusedList.add(overtimetxused);
				Integer integer = otuSeq;
				Integer integer3 = otuSeq = Integer
						.valueOf(otuSeq.intValue() + 1);
				Integer _tmp = integer;
				tiaoxiuOr.setOrTiaoxiuHoursRemain(new BigDecimal(0.0D));
				needUpdateOvertimerequestList.add(tiaoxiuOr);
				iter.remove();
				lrHours -= tiaoxiuHours;
				continue;
			}
			if (lrHours == tiaoxiuHours) {
				overtimetxused = new Overtimetxused();
				overtimetxused.setOtuLrId(lr);
				overtimetxused.setOtuOrId(tiaoxiuOr);
				overtimetxused.setOtuHours(new BigDecimal(tiaoxiuHours));
				overtimetxused.setOtuDays(new BigDecimal(tiaoxiuHours
						/ hourPerDay));
				overtimetxused.setOtuSeq(otuSeq);
				updateOvertimetxusedList.add(overtimetxused);
				Integer integer1 = otuSeq;
				Integer integer4 = otuSeq = Integer
						.valueOf(otuSeq.intValue() + 1);
				Integer _tmp1 = integer1;
				tiaoxiuOr.setOrTiaoxiuHoursRemain(new BigDecimal(0.0D));
				needUpdateOvertimerequestList.add(tiaoxiuOr);
				iter.remove();
				lrHours = 0.0D;
				break;
			}
			if (lrHours >= tiaoxiuHours)
				continue;
			overtimetxused = new Overtimetxused();
			overtimetxused.setOtuLrId(lr);
			overtimetxused.setOtuOrId(tiaoxiuOr);
			overtimetxused.setOtuHours(new BigDecimal(lrHours));
			overtimetxused.setOtuDays(new BigDecimal(lrHours / hourPerDay));
			overtimetxused.setOtuSeq(otuSeq);
			updateOvertimetxusedList.add(overtimetxused);
			Integer integer2 = otuSeq;
			Integer integer5 = otuSeq = Integer.valueOf(otuSeq.intValue() + 1);
			Integer _tmp2 = integer2;
			tiaoxiuOr.setOrTiaoxiuHoursRemain(new BigDecimal(tiaoxiuHours
					- lrHours));
			needUpdateOvertimerequestList.add(tiaoxiuOr);
			lrHours = 0.0D;
			break;
		} while (true);
		if (lr.getUpdateOvertimerequestList() == null)
			lr.setUpdateOvertimerequestList(needUpdateOvertimerequestList);
		else
			lr.getUpdateOvertimerequestList().addAll(
					needUpdateOvertimerequestList);
		if (lr.getUpdateOvertimetxusedList() == null)
			lr.setUpdateOvertimetxusedList(updateOvertimetxusedList);
		else
			lr.getUpdateOvertimetxusedList().addAll(updateOvertimetxusedList);
		return lrHours;
	}

	public String checkAnnual(Leaverequest lr, Leavetype lt, Leavebalance lb) {
		int currentYear = Integer.parseInt(lb.getLbYear());
		Date yearBeginDate = DateUtil.getYearFirstDay(currentYear);
		Date yearEndDate = DateUtil.getYearEndDay(currentYear);
		Date nextYearBeginDate = DateUtil.getNextYearFirstDay(currentYear);
		List annualLRList = getValidLRs(lr, yearBeginDate, yearEndDate);
		Double balFwdHours = getBalFwdHours(lb, lr.getHoursPerDay());
		Double wastedHours;
		Double allHours;
		if (lb.getLbBalEndDate() == null) {
			wastedHours = new Double(0.0D);
			allHours = Double.valueOf(getLeaveHoursBeforAfter(annualLRList,
					nextYearBeginDate)[0]);
		} else {
			double allHoursArr[] = getLeaveHoursBeforAfter(annualLRList, lb
					.getLbBalEndDate());
			wastedHours = Double.valueOf(allHoursArr[0] >= balFwdHours
					.doubleValue() ? (new Double(0.0D)).doubleValue()
					: balFwdHours.doubleValue() - allHoursArr[0]);
			allHours = Double.valueOf(allHoursArr[0] + allHoursArr[1]);
		}
		Date endDate = ((Leaverequest) annualLRList
				.get(annualLRList.size() - 1)).getLrStartDate();
		Double releaseHours = getReleaseHours(lb, lt, endDate, lr
				.getHoursPerDay());
		if (allHours.doubleValue() > (balFwdHours.doubleValue() + releaseHours
				.doubleValue())
				- wastedHours.doubleValue())
			return "\u5DF2\u8BF7\u5E74\u5047\u603B\u65F6\u95F4\u8D85\u8FC7\u53EF\u8BF7\u4E0A\u9650\uFF0C\u64CD\u4F5C\u5931\u8D25\uFF01";
		setUsageTime(lr, allHours.doubleValue(), balFwdHours.doubleValue(),
				releaseHours.doubleValue(), wastedHours.doubleValue());
		for (int i = annualLRList.size() - 1; i >= 0
				&& lr.getLrStartDate().compareTo(
						((Leaverequest) annualLRList.get(i)).getLrStartDate()) != 0; i--) {
			allHours = Double.valueOf(allHours.doubleValue()
					- ((Leaverequest) annualLRList.get(i)).getLrTotalHours()
							.doubleValue());
			releaseHours = getReleaseHours(lb, lt, ((Leaverequest) annualLRList
					.get(i)).getLrStartDate(), lr.getHoursPerDay());
			if (allHours.doubleValue() > (balFwdHours.doubleValue() + releaseHours
					.doubleValue())
					- wastedHours.doubleValue())
				return "\u5DF2\u8BF7\u5E74\u5047\u603B\u65F6\u95F4\u8D85\u8FC7\u53EF\u8BF7\u4E0A\u9650\uFF0C\u64CD\u4F5C\u5931\u8D25\uFF01";
		}

		return "SUCC";
	}

	public Double getBalFwdHours(Leavebalance lb, double hourPerDay) {
		if (lb.getLbBalForwardDay() != null)
			return Double.valueOf(lb.getLbBalForwardDay().doubleValue()
					* hourPerDay);
		if (lb.getLbBalForwardHour() != null)
			return Double.valueOf(lb.getLbBalForwardHour().doubleValue());
		else
			return new Double(0.0D);
	}

	public Double getCurrYearHours(Leavebalance lb, double hourPerDay) {
		if (lb.getLbDaysOfYear() != null)
			return Double.valueOf(lb.getLbDaysOfYear().doubleValue()
					* hourPerDay);
		if (lb.getLbHoursOfYear() != null)
			return Double.valueOf(lb.getLbHoursOfYear().doubleValue());
		else
			return new Double(0.0D);
	}

	public Double getReleaseHours(Leavebalance lb, Leavetype lt,
			Date yearToDate, double hourPerDay) {
		Double currYearHours = getCurrYearHours(lb, hourPerDay);
		if (lt.getLtReleaseMethod() == null)
			return currYearHours;
		Double releaseHours = new Double(0.0D);
		if (lb.getLbDaysForRelease() != null)
			releaseHours = Double.valueOf(lb.getLbDaysForRelease()
					.doubleValue()
					* hourPerDay);
		else if (lb.getLbHoursForRelease() != null)
			releaseHours = Double.valueOf(lb.getLbHoursForRelease()
					.doubleValue());
		else
			releaseHours = currYearHours;
		int currentYear = DateUtil.getYear(yearToDate);
		Date yearBeginDate = DateUtil.getYearFirstDay(currentYear);
		Date yearEndDate = DateUtil.getYearEndDay(currentYear);
		Date relBeginDate = yearBeginDate;
		if (lb.getLbReleaseStartDate() != null
				&& DateUtil.getYear(lb.getLbReleaseStartDate()) == DateUtil
						.getYear(yearBeginDate))
			relBeginDate = lb.getLbReleaseStartDate();
		double monthsOfYear = (12 - DateUtil.getMonth(relBeginDate)) + 1;
		double monthToDate = (DateUtil.getMonth(yearToDate) - DateUtil
				.getMonth(relBeginDate)) + 1;
		double factor_M = monthToDate / monthsOfYear;
		double daysOfYear = 1 + DateUtil.dateDiff(relBeginDate, yearEndDate, 5);
		double daysToDate = 1 + DateUtil.dateDiff(relBeginDate, yearToDate, 5);
		double factor_D = daysToDate / daysOfYear;
		if ("M".equals(lt.getLtReleaseMethod()))
			releaseHours = Double
					.valueOf(factor_M * releaseHours.doubleValue());
		else if ("D".equals(lt.getLtReleaseMethod()))
			releaseHours = Double
					.valueOf(factor_D * releaseHours.doubleValue());
		else
			releaseHours = currYearHours;
		if (releaseHours.doubleValue() > currYearHours.doubleValue()) {
			return currYearHours;
		} else {
			releaseHours = Double.valueOf(processByRound(releaseHours
					.doubleValue(), lt.getLtReleaseRounding()));
			return releaseHours;
		}
	}

	public String checkSick02(Leaverequest lr, Leavetype lt, Leavebalance lb) {
		int currentYear = Integer.parseInt(lb.getLbYear());
		Date yearBeginDate = DateUtil.getYearFirstDay(currentYear);
		Date yearEndDate = DateUtil.getYearEndDay(currentYear);
		Date nextYearBeginDate = DateUtil.getNextYearFirstDay(currentYear);
		double hourPerDay = ExaminDateUtil.getDefaultHoursPerDay();
		List sick02LRList = getValidLRs(lr, yearBeginDate, yearEndDate);
		Double allHours = Double.valueOf(getLeaveHoursBeforAfter(sick02LRList,
				nextYearBeginDate)[0]);
		Date endDate = ((Leaverequest) sick02LRList
				.get(sick02LRList.size() - 1)).getLrStartDate();
		Double releaseHours = getReleaseHours(lb, lt, endDate, hourPerDay);
		if (allHours.doubleValue() > releaseHours.doubleValue())
			return "\u5DF2\u8BF7\u5E26\u85AA\u75C5\u5047\u603B\u65F6\u95F4\u8D85\u8FC7\u53EF\u8BF7\u4E0A\u9650\uFF0C\u64CD\u4F5C\u5931\u8D25\uFF01";
		setUsageTime(lr, allHours.doubleValue(), 0.0D, releaseHours
				.doubleValue(), 0.0D);
		for (int i = sick02LRList.size() - 1; i >= 0
				&& lr.getLrStartDate().compareTo(
						((Leaverequest) sick02LRList.get(i)).getLrStartDate()) != 0; i--) {
			allHours = Double.valueOf(allHours.doubleValue()
					- ((Leaverequest) sick02LRList.get(i)).getLrTotalHours()
							.doubleValue());
			releaseHours = getReleaseHours(lb, lt, ((Leaverequest) sick02LRList
					.get(i)).getLrStartDate(), hourPerDay);
			if (allHours.doubleValue() > releaseHours.doubleValue())
				return "\u5DF2\u8BF7\u5E26\u85AA\u75C5\u5047\u603B\u65F6\u95F4\u8D85\u8FC7\u53EF\u8BF7\u4E0A\u9650\uFF0C\u64CD\u4F5C\u5931\u8D25\uFF01";
		}

		return "SUCC";
	}

	private void setUsageTime(Leaverequest lr, double allHours,
			double balFwdHours, double releaseHours, double wastedHours) {
		double temp = (balFwdHours + releaseHours) - wastedHours;
		lr.setUseableHours(new BigDecimal(MyTools.round(temp, 2)));
		lr.setUseableDays(new BigDecimal(MyTools.round(temp
				/ lr.getHoursPerDay(), 2)));
		temp = allHours;
		lr.setUsedHours(new BigDecimal(MyTools.round(temp, 2)));
		lr.setUsedDays(new BigDecimal(MyTools.round(temp / lr.getHoursPerDay(),
				2)));
		temp = (balFwdHours + releaseHours) - wastedHours - allHours;
		lr.setRemainHours(new BigDecimal(MyTools.round(temp, 2)));
		lr.setRemainDays(new BigDecimal(MyTools.round(temp
				/ lr.getHoursPerDay(), 2)));
	}

	public double processByRound(double value, Integer roundType) {
		double result;
		switch (roundType.intValue()) {
		case 1: // '\001'
			result = MyTools.floor(value, 0);
			break;

		case 2: // '\002'
			result = MyTools.round(value, 0);
			break;

		case 3: // '\003'
			result = MyTools.ceil(value, 0);
			break;

		case 4: // '\004'
			result = MyTools.floor(value * 2D, 0) / 2D;
			break;

		case 5: // '\005'
			result = MyTools.round(value * 2D, 0) / 2D;
			break;

		case 6: // '\006'
			result = MyTools.ceil(value * 2D, 0) / 2D;
			break;

		default:
			result = MyTools.round(value, 2);
			break;
		}
		return result;
	}

	/**
	 * @deprecated Method getTotalStatusSetList is deprecated
	 */

	public List getTotalStatusSetList(Leaverequest lr, Date startDate,
			Date endDate, int statusSet[]) {
		Integer statusSet1[] = new Integer[statusSet.length];
		for (int i = 0; i < statusSet.length; i++)
			statusSet1[i] = Integer.valueOf(statusSet[i]);

		DetachedCriteria detachedCrteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_EMP_NO, lr
				.getLrEmpNo()));
		detachedCrteria.add(Restrictions.or(Restrictions.and(Restrictions.ge(
				Leaverequest.PROP_LR_START_DATE, startDate), Restrictions.lt(
				Leaverequest.PROP_LR_START_DATE, endDate)), Restrictions.and(
				Restrictions.le(Leaverequest.PROP_LR_END_DATE, endDate),
				Restrictions.gt(Leaverequest.PROP_LR_END_DATE, startDate))));
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_LT_NO, lr
				.getLrLtNo()));
		detachedCrteria.add(Restrictions.in(Leaverequest.PROP_LR_STATUS,
				statusSet1));
		if (lr.getLrId() != null && !lr.getLrId().equals(""))
			detachedCrteria.add(Restrictions.ne(Leaverequest.PROP_LR_ID, lr
					.getLrId()));
		List result = getLr_DAO().findByCriteria(detachedCrteria);
		return result;
	}

	private List getValidLRs(Leaverequest lr, Date startDate, Date endDate) {
		if (startDate == null)
			startDate = DateUtil.convYMToMonFirst("190001");
		if (endDate == null)
			endDate = DateUtil.convYMToMonEnd("209912");
		DetachedCriteria detachedCrteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_EMP_NO, lr
				.getLrEmpNo()));
		detachedCrteria.add(Restrictions.or(Restrictions.and(Restrictions.ge(
				Leaverequest.PROP_LR_START_DATE, startDate), Restrictions.lt(
				Leaverequest.PROP_LR_START_DATE, endDate)), Restrictions.and(
				Restrictions.le(Leaverequest.PROP_LR_END_DATE, endDate),
				Restrictions.gt(Leaverequest.PROP_LR_END_DATE, startDate))));
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_LT_NO, lr
				.getLrLtNo()));
		detachedCrteria.addOrder(Order.asc(Leaverequest.PROP_LR_START_DATE));
		List lrList = getLr_DAO().findByCriteria(detachedCrteria);
		List result = new LinkedList();
		int index = 0;
		Iterator i$ = lrList.iterator();
		do {
			if (!i$.hasNext())
				break;
			Leaverequest lrTemp = (Leaverequest) i$.next();
			if (lrTemp.getLrStatus().intValue() != 21
					&& lrTemp.getLrStatus().intValue() != 22
					&& !lrTemp.getLrId().equals(lr.getLrId())) {
				result.add(lrTemp);
				if (lr.getLrStartDate().after(lrTemp.getLrStartDate()))
					index++;
			}
		} while (true);
		result.add(index, lr);
		return result;
	}

	public int hasDateRepeat(Leaverequest lr, Date startDate, Date endDate,
			Integer statusSet[]) {
		DetachedCriteria detachedCrteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_EMP_NO, lr
				.getLrEmpNo()));
		detachedCrteria.add(Restrictions.in(Leaverequest.PROP_LR_STATUS,
				statusSet));
		Date startTime = lr.getLrStartDate();
		Date endTime = lr.getLrEndDate();
		detachedCrteria.add(Restrictions.lt(Leaverequest.PROP_LR_START_DATE,
				endTime));
		detachedCrteria.add(Restrictions.gt(Leaverequest.PROP_LR_END_DATE,
				startTime));
		List resultList = lr_DAO.findByCriteria(detachedCrteria);
		if (resultList == null || resultList.size() == 0)
			return -1;
		if (resultList.size() == 1
				&& ((Leaverequest) resultList.get(0)).getLrId().equals(
						lr.getLrId()))
			return -1;
		else
			return ((Leaverequest) resultList.get(0)).getLrNo().intValue();
	}

	public double[] getLeaveHoursBeforAfter(List inputlist, Date checkDate) {
		double result[] = new double[2];
		for (Iterator i$ = inputlist.iterator(); i$.hasNext();) {
			Leaverequest lr = (Leaverequest) i$.next();
			if (DateUtil.dateDiff(checkDate, lr.getLrStartDate(), 5) > 1)
				result[1] += lr.getLrTotalHours().doubleValue();
			else if (DateUtil.dateDiff(checkDate, lr.getLrEndDate(), 5) <= 0) {
				result[0] += lr.getLrTotalHours().doubleValue();
			} else {
				double totalBefore = 0.0D;
				if (lr.getLrStartApm() == null) {
					List shiftList = null;
					if (lr.getLrEmpNo().getEmpShiftType().intValue() == 3) {
						shiftList = empShiftBo.getEmpShiftList(DateUtil
								.dateAdd(lr.getLrStartDate(), -1), checkDate,
								lr.getLrEmpNo().getId());
					} else {
						List lcList = lc_BO.getCalendarListByDay(lr
								.getLrStartDate(), checkDate);
						Attendshift defaultAs = attendBo
								.getDefaultAttendshiftByEmp(lr.getLrEmpNo());
						shiftList = generateDefaultESList(lr.getLrStartDate(),
								lr.getLrEndDate(), lr.getLrEmpNo(), defaultAs,
								lcList);
					}
					totalBefore = getHoursByShift(lr, checkDate, shiftList);
				} else if (lr.getLrEmpNo().getEmpShiftType().intValue() == 3)
					totalBefore = getDaysByShift(lr, checkDate);
				else
					totalBefore = getDaysByCal(lr, checkDate);
				if (totalBefore > lr.getLrTotalHours().doubleValue())
					totalBefore = lr.getLrTotalHours().doubleValue();
				result[0] += totalBefore;
				result[1] += lr.getLrTotalHours().doubleValue() - totalBefore;
			}
		}

		return result;
	}

	public double getDaysByCal(Leaverequest lr, Date endDate) {
		List lcList = lc_BO.getCalendarListByDay(lr.getLrStartDate(), endDate);
		double totalDays = lc_BO.getWorkDays(lr.getLrStartDate(), endDate,
				lcList, lr.getLrEmpNo().getEmpLocationNo());
		if (lr.getLrStartApm().intValue() == 1)
			totalDays -= 0.5D;
		double hoursPerDay = ExaminDateUtil.getDefaultHoursPerDay();
		return totalDays * hoursPerDay;
	}

	private double getHoursByShift(Leaverequest lr, Date checkDate,
			List<Empshift> shiftList) {
		Empshift lastES = null;
		if ((shiftList == null) || (shiftList.size() == 0))
			return 0.0D;
		for (Empshift es : shiftList) {
			if (DateUtil.dateDiff(checkDate, es.getEmpshiftDate(), 5) > 0)
				break;
			try {
				lastES = (Empshift) es.clone();
			} catch (CloneNotSupportedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if (lastES == null)
			return 0.0D;
		Date[] lastESArr = ExaminDateUtil.getShiftArr(lastES.getEmpshiftDate(),
				lastES.getEmpshiftShiftNo().getAttsSession());
		double totalHours = 0.0D;
		if (lr.getLrEndDate().before(lastESArr[1]))
			totalHours = getEmpShiftBo().computeTotalLeaveMinutes(
					lr.getLrStartDate(), lr.getLrEndDate(), shiftList) / 60.0D;
		else {
			totalHours = getEmpShiftBo().computeTotalLeaveMinutes(
					lr.getLrStartDate(), lastESArr[1], shiftList) / 60.0D;
		}
		totalHours = MyTools.round(totalHours, 2);
		return totalHours;
	}

	private double getDaysByShift(Leaverequest lr, Date checkDate) {
		List list = getEmpShiftBo().getEmpShiftList(lr.getLrStartDate(),
				checkDate, lr.getLrEmpNo().getId());
		if (list == null || list.size() == 0)
			return 0.0D;
		double totalDays = list.size();
		if (lr.getLrStartApm().intValue() == 1)
			totalDays -= 0.5D;
		double hoursPerDay = ExaminDateUtil.getDefaultHoursPerDay();
		return totalDays * hoursPerDay;
	}

	public double[] getAnnualLeaveDate(Employee currEmp, Leavetype lt,
			Leavebalance lb) {
		int currentYear = Integer.parseInt(lb.getLbYear());
		Date yearBeginDate = DateUtil.getYearFirstDay(currentYear);
		Date yearEndDate = DateUtil.getYearEndDay(currentYear);
		Date nextYearBeginDate = DateUtil.getNextYearFirstDay(currentYear);
		IAttendshiftBO attendBo = (IAttendshiftBO) SpringBeanFactory
				.getBean("attendshiftBO");
		Attendshift defaultAs = attendBo.getDefaultAttendshiftByEmp(currEmp);
		double hoursPerDay;
		if (currEmp.getEmpShiftType().intValue() == 0
				|| currEmp.getEmpShiftType().intValue() == 2)
			hoursPerDay = defaultAs.getAttsWorkingHour().doubleValue();
		else
			hoursPerDay = ExaminDateUtil.getDefaultHoursPerDay();
		List annualLRList = getValidLRs(lt, currEmp, yearBeginDate, yearEndDate);
		Double balFwdHours = getBalFwdHours(lb, hoursPerDay);
		Double wastedHours;
		Double allHours;
		if (lb.getLbBalEndDate() == null) {
			wastedHours = new Double(0.0D);
			allHours = Double.valueOf(getLeaveHoursBeforAfter(annualLRList,
					nextYearBeginDate)[0]);
		} else {
			double allHoursArr[] = getLeaveHoursBeforAfter(annualLRList, lb
					.getLbBalEndDate());
			wastedHours = Double.valueOf(allHoursArr[0] >= balFwdHours
					.doubleValue() ? (new Double(0.0D)).doubleValue()
					: balFwdHours.doubleValue() - allHoursArr[0]);
			allHours = Double.valueOf(allHoursArr[0] + allHoursArr[1]);
		}
		Date endDate = new Date();
		Double releaseHours = getReleaseHours(lb, lt, endDate, hoursPerDay);
		double result[] = {
				allHours.doubleValue(),
				(balFwdHours.doubleValue() + releaseHours.doubleValue())
						- wastedHours.doubleValue() - allHours.doubleValue() };
		return result;
	}

	private List getValidLRs(Leavetype leavetype, Employee currEmp,
			Date startDate, Date endDate) {
		if (startDate == null)
			startDate = DateUtil.convYMToMonFirst("190001");
		if (endDate == null)
			endDate = DateUtil.convYMToMonEnd("209912");
		DetachedCriteria detachedCrteria = DetachedCriteria
				.forClass(com.wyzz.hr.pojo.Leaverequest.class);
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_EMP_NO,
				currEmp));
		detachedCrteria.add(Restrictions.or(Restrictions.and(Restrictions.ge(
				Leaverequest.PROP_LR_START_DATE, startDate), Restrictions.lt(
				Leaverequest.PROP_LR_START_DATE, endDate)), Restrictions.and(
				Restrictions.le(Leaverequest.PROP_LR_END_DATE, endDate),
				Restrictions.gt(Leaverequest.PROP_LR_END_DATE, startDate))));
		detachedCrteria.add(Restrictions.eq(Leaverequest.PROP_LR_LT_NO,
				leavetype));
		detachedCrteria.addOrder(Order.asc(Leaverequest.PROP_LR_START_DATE));
		detachedCrteria.add(Restrictions.in(Leaverequest.PROP_LR_STATUS,
				Status.PROCESSED));
		List lrList = getLr_DAO().findByCriteria(detachedCrteria);
		return lrList;
	}

	public double[] getSick02LeaveDate(Employee currEmp, Leavetype lt,
			Leavebalance lb) {
		int currentYear = Integer.parseInt(lb.getLbYear());
		Date yearBeginDate = DateUtil.getYearFirstDay(currentYear);
		Date yearEndDate = DateUtil.getYearEndDay(currentYear);
		Date nextYearBeginDate = DateUtil.getNextYearFirstDay(currentYear);
		double hourPerDay = ExaminDateUtil.getDefaultHoursPerDay();
		List sick02LRList = getValidLRs(lt, currEmp, yearBeginDate, yearEndDate);
		Double allHours = Double.valueOf(getLeaveHoursBeforAfter(sick02LRList,
				nextYearBeginDate)[0]);
		Date endDate = new Date();
		Double releaseHours = getReleaseHours(lb, lt, endDate, hourPerDay);
		double result[] = { allHours.doubleValue(),
				releaseHours.doubleValue() - allHours.doubleValue() };
		return result;
	}

	public ILeaverequestDAO getLr_DAO() {
		return lr_DAO;
	}

	public void setLr_DAO(ILeaverequestDAO lr_DAO) {
		this.lr_DAO = lr_DAO;
	}

	public ILeavebalanceBO getLb_BO() {
		return lb_BO;
	}

	public void setLb_BO(ILeavebalanceBO lb_BO) {
		this.lb_BO = lb_BO;
	}

	public ILeavecalendarBO getLc_BO() {
		return lc_BO;
	}

	public void setLc_BO(ILeavecalendarBO lc_BO) {
		this.lc_BO = lc_BO;
	}

	public IEmpshiftBo getEmpShiftBo() {
		return empShiftBo;
	}

	public void setEmpShiftBo(IEmpshiftBo empShiftBo) {
		this.empShiftBo = empShiftBo;
	}

	public IAttendshiftBO getAttendBo() {
		return attendBo;
	}

	public void setAttendBo(IAttendshiftBO attendBo) {
		this.attendBo = attendBo;
	}

	public IOvertimerequestBo getOr_Bo() {
		return or_Bo;
	}

	public void setOr_Bo(IOvertimerequestBo or_Bo) {
		this.or_Bo = or_Bo;
	}

	public static int statusSet_approved[] = { 15, 16 };
	public static final int MILLSECONDONEDAY = 0x5265c00;
	private IEmpshiftBo empShiftBo;
	private IAttendshiftBO attendBo;
	private IOvertimerequestBo or_Bo;
	private ILeaverequestDAO lr_DAO;
	private ILeavebalanceBO lb_BO;
	private ILeavecalendarBO lc_BO;

}
